<template>
  <div class="tinymce-editor">
    <Editor :id="editorId" style="width: 100%" v-model="myValue" :init="init" :disabled="disabled" @onClick="onClick" />
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, onMounted, watch, onBeforeUnmount } from 'vue'
  import Editor from '@tinymce/tinymce-vue'
  import tinymce from 'tinymce/tinymce'

  //引入图标和主题等
  import 'tinymce/themes/silver/theme'
  import 'tinymce/icons/default'
  import 'tinymce/models/dom'

  //引入插件
  import 'tinymce/plugins/codesample' // 代码块
  import 'tinymce/plugins/lists' // 列表
  import 'tinymce/plugins/advlist' // 列表
  import 'tinymce/plugins/link' // 超链接
  import 'tinymce/plugins/autolink' // 自动链接
  import 'tinymce/plugins/charmap' // 特殊字符
  import 'tinymce/plugins/fullscreen' // 全屏
  import 'tinymce/plugins/preview' // 预览
  import 'tinymce/plugins/code' // 代码
  import 'tinymce/plugins/searchreplace' // 查找替换
  import 'tinymce/plugins/table' // 表格
  import 'tinymce/plugins/visualblocks' // 显示块级元素
  import 'tinymce/plugins/wordcount' // 字数统计
  import 'tinymce/plugins/insertdatetime' // 插入时间
  import 'tinymce/plugins/image' // 图片上传
  import 'tinymce/plugins/importcss' // 图片上传

  import { personalOptions, varOptions } from './var-options'

  const props = defineProps({
    id: Number,
    value: {
      type: String,
    },
    clientType: {
      type: [String, Number],
      default: '',
    },
    triggerChange: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    plugins: {
      type: [String, Array],
      default:
        'codesample lists advlist link autolink charmap fullscreen preview code searchreplace table visualblocks wordcount insertdatetime image importcss',
    },
    toolbar: {
      type: [String, Array],
      default:
        'bold italic underline strikethrough blockquote bullist numlist outdent indent fontsize blocks forecolor backcolor ' +
        ' alignleft aligncenter alignright removeformat image importcss code mybutton',
    },
  })

  // 增加一个编辑器id，多个的时候tinymce销毁对应的编辑器
  const editorId = `tinymce_editor_${props.id || Date.now()}`

  const init = reactive({
    selector: `${editorId} textarea`,
    // 设置本地主题
    skin_url: '/tinymce/skins/ui/oxide',
    // 设置本地css
    content_css: '/tinymce/skins/content/default/content.css',
    // 设置本地语言
    language_url: '/tinymce/langs/zh-Hans.js',
    language: 'zh-Hans',
    height: 600,
    plugins: props.plugins,
    toolbar: props.toolbar,
    // paste_data_images: false, // 禁止粘贴图片
    // paste_as_text: true,
    // paste_block_drop: false,
    // 底部状态栏
    statusbar: false,
    // 顶部菜单栏
    menubar: false,
    placeholder: '在这里输入文字',
    font_size_formats: '12px 14px 16px 18px 20px 21px 24px 36px 48px 56px 72px',
    font_family_formats:
      '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;',
    // 初始化完成
    init_instance_callback: (editor: any) => {
      console.log('初始化完成：', editor)
    },
    // 上传图片
    images_upload_handler: (blobInfo: any, progress: any) => {
      return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.withCredentials = false
        xhr.open('POST', `${import.meta.env.VITE_BASE_PATH}/uploadFile/specialUpload`)

        xhr.upload.onprogress = (e) => {
          progress((e.loaded / e.total) * 100)
        }

        xhr.onload = () => {
          if (xhr.status === 403) {
            reject({ message: 'HTTP Error: ' + xhr.status, remove: true })
            return
          }

          if (xhr.status < 200 || xhr.status >= 300) {
            reject('HTTP Error: ' + xhr.status)
            return
          }

          const json = JSON.parse(xhr.responseText)

          if (!json || json.result.length === 0) {
            reject('Invalid JSON: ' + xhr.responseText)
            return
          }

          resolve(json.result[0].openUrl)
        }

        xhr.onerror = () => {
          reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status)
        }

        const formData = new FormData()
        formData.append('files', blobInfo.blob(), blobInfo.filename())

        xhr.send(formData)
      })
    },
    setup: (editor: any) => {
      editor.ui.registry.addMenuButton('mybutton', {
        text: '插入合同变量参数',
        tooltip: '选择合同变量参数插入合同模板中',
        fetch: (callback: any) => {
          props.clientType == 2 ? callback(personalOptions(editor)) : callback(varOptions(editor))
        },
      })
    },
  })
  const emits = defineEmits(['onClick', 'change', 'input'])
  const myValue = ref(props.value)

  const onClick = (e: any) => {
    emits('onClick', e, tinymce)
  }

  //可以添加一些自己的自定义事件，如清空内容
  const clear = () => {
    myValue.value = ''
  }

  onMounted(() => {
    tinymce.init({})
  })

  onBeforeUnmount(() => {
    tinymce.remove(`${editorId} textarea`)
  })

  watch(
    () => props.value,
    (val) => {
      myValue.value = val === null ? '' : val
    }
  )
  watch(
    () => props.clientType,
    (val) => {
      console.log('clientType', val)
      tinymce.init({})
    }
  )

  watch(
    () => myValue.value,
    (val) => {
      if (props.triggerChange) {
        emits('change', val, tinymce)
      } else {
        emits('input', val, tinymce)
      }
    }
  )

  defineExpose({
    clear,
  })
</script>
<style lang="less" scoped>
  :deep(.tox .tox-tbtn--select) {
    color: #165dff;
  }
  :deep(.tox .tox-tbtn--bespoke + .tox-tbtn--bespoke) {
    color: #222f3e;
  }
  :deep(.tox .tox-tbtn--bespoke) {
    color: #222f3e;
  }
</style>
